﻿using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Xml.Linq;
using Schema = QASPRibbon.RibbonSchema;

namespace QASPRibbon.Controls
{
    internal class RibbonGroupTemplateDef : RibbonElement
    {
        public RibbonDisplayMode Mode;

        internal string XML;

        internal override string XmlTag
        {
            get { return Schema.GroupTemplate; }
        }

        internal override XElement AsXElement()
        {
            return new XElement(XmlTag);
        }

        private static string GetSectionTypeName(RibbonSectionType type)
        {
            switch (type)
            {
                case RibbonSectionType.OneRow: return Schema.OneRow;
                case RibbonSectionType.TwoRows: return Schema.TwoRow;
                case RibbonSectionType.ThreeRows: return Schema.ThreeRow;
            }
            return Schema.Divider;
        }

        public static string GetRibbonDisplayMode(RibbonDisplayMode controlMode)
        {
            switch (controlMode)
            {
                case RibbonDisplayMode.Image16Only: return Schema.Small;
                case RibbonDisplayMode.Image16AndCaption: return Schema.Medium;
                case RibbonDisplayMode.Image32AndCaption: return Schema.Large;
                case RibbonDisplayMode.CaptionOnly: return Schema.Menu;
            }
            return string.Empty;
        }

        public RibbonGroupTemplateDef(RibbonGroup group)
        {
            Id = group.Id + Schema.Template;
            NameSpace = "Ribbon.Templates";
            var xml = new XElement(Schema.GroupTemplate,
                                   new XAttribute(Schema.Id, group.FullId + Schema.Template));
            var layout = new XElement(Schema.Layout,
                                      new XAttribute(Schema.Title, group.FullId + Schema.Layout));
            xml.Add(layout);
            
            var sections = BuildSections(group);
            layout.Add(sections);

            //var ss = new XElement(Schema.Layout,
            //                      new XAttribute(Schema.Title, "Medium"));
            //var of = BuildOverflowSections(group, "Small");

            //ss.Add(of);
            //xml.Add(ss);

            //var ss2 = new XElement(Schema.Layout,
            //                      new XAttribute(Schema.Title, "LargeMedium"));
            //var of2 = BuildOverflowSections(group, "Small");

            //ss.Add(of2);
            //xml.Add(ss2);

            xml.Add(new XElement(Schema.Layout, 
                new XAttribute(Schema.Title, "Popup"), 
                new XAttribute(Schema.LayoutTitle, group.FullId + Schema.Layout)));
            XML = xml.ToString();

            Debug.WriteLine("Ribbon Template: \r\n" + XML);
        }

        private static IEnumerable<XElement> BuildSections(RibbonGroup group)
        {
            var res = new List<XElement>();
            var sectionIndex = 0;
            foreach (var section in group.Sections)
            {
                if (section.Controls == null)
                    continue;
                // Индекс секции
                sectionIndex++;
                var controlIndex = 0;
                var stripIndex = 0;
                var sectionControls = new Dictionary<int, RibbonControl>();
                foreach (var control in section.Controls)
                {
                    controlIndex++;
                    sectionControls.Add(controlIndex, control);
                }
                controlIndex = 0;
                if (section.Type == RibbonSectionType.Divider)
                {
                    res.Add(new XElement(Schema.Section, new XAttribute(Schema.Type, Schema.Divider)));
                }
                else
                {
                    // XML секции
                    var sectionXml = new XElement(Schema.Section,
                                                   new XAttribute(Schema.Type, GetSectionTypeName(section.Type)),
                                                   new XAttribute(Schema.Alignment,
                                                                  section.Alignment == RibbonSectionAlignment.Top
                                                                      ? "Top"
                                                                      : "Middle"));

                    

                    // Кол-во строк в секции
                    var rowQnt = (int)section.Type;
                    for (var i = 1; i <= rowQnt; i++)
                    {
                        var templateAlias = string.Format("{0}Layout{1}{2}Row{3}",
                                                      group.FullId,
                                                      sectionIndex,
                                                      GetRibbonDisplayMode(section.DisplayMode),
                                                      i);

                        // XML строки
                        var rowXml = new XElement(Schema.Row);

                        var rowControls = sectionControls
                            .Where(x => x.Key % i == 0)
                            .Select(c=>c.Value)
                            .ToList();
                        foreach (var control in rowControls)
                        {
                            controlIndex++;
                            var ribbonStrip = control as RibbonStrip;
                            if (ribbonStrip != null)
                            {
                                var s = ribbonStrip;
                                var row = new XElement(Schema.Row);
                                var strip = new XElement(Schema.Strip);
                                foreach (var stripControl in s.Controls)
                                {
                                    stripIndex++;
                                    strip.Add(new XElement(Schema.ControlRef,
                                                           new XAttribute(Schema.DisplayMode,
                                                                          GetRibbonDisplayMode(section.DisplayMode)),
                                                           new XAttribute(Schema.TemplateAlias,
                                                                          templateAlias + "S" + stripIndex)));
                                    stripControl.TemplateAlias = templateAlias + "S" + stripIndex;
                                }
                                row.Add(strip);
                            }
                            else
                            {
                                control.TemplateAlias = templateAlias + "C" + controlIndex;
                                rowXml.Add(new XElement(Schema.ControlRef,
                                             new XAttribute(Schema.DisplayMode, GetRibbonDisplayMode(section.DisplayMode)),
                                             new XAttribute(Schema.TemplateAlias, templateAlias + "C" + controlIndex)));
                            }
                        }

                        sectionXml.Add(rowXml);
                    }
                    res.Add(sectionXml);
                }
            }
            
            return res;
        }
    }
}
